package com.gobang.model;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.ImageIcon;

/**
 * 棋盘
 * @author rzpeng
 *
 */
public class Chessboard {
	/*
	 * 棋盘和棋子的常量
	 */
	public static final int PIECE_WHITE = 1;	// 白棋
	public static final int PIECE_BLACK = 2;	// 黑棋
	public static final int PIECE_SIZE = 30;	//棋子大小
	public static final int GRID_NUM = 14;		//格子数量
	public static final int GRID_SIZE = 35;		//格子大小
	public static final int BOARD_PADDING = 30; //棋盘内边距 
	
	/**
	 * 棋盘上的棋子
	 * 
	 */
	private int[][] pieces;
	
	/**
	 * 当前颜色
	 */
	private int currentColor;
	
	/**
	 * 游戏是否已经结束
	 */
	private boolean isOver;
	
	/**
	 * 构造方法
	 * 先下的颜色
	 * @param firstColor
	 */
	public Chessboard(int firstColor){
		init(firstColor);
	}
	
	/**
	 * 初始化棋盘信息
	 * @param firstColor
	 */
	public void init(int firstColor){
		checkColor(firstColor);
		pieces = new int[GRID_NUM+1][GRID_NUM+1];
		currentColor = firstColor;
		isOver = false;
	}
	
	private void checkColor(int color){
		if(color != PIECE_WHITE && color != PIECE_BLACK){
			throw new RuntimeException("不支持该棋子颜色!");
		}
	}
	
	private void checkPosition(int x, int y){
		if(x < 0 || x > GRID_NUM){
			throw new RuntimeException("棋子横坐标越界");
		}
		if( y < 0 || y > GRID_NUM){
			throw new RuntimeException("棋子纵坐标越界");
		}
	}
	
	public int putChess(int color, int x, int y){
		if(color != currentColor){
			throw new RuntimeException("现在没有轮到您下棋，请等候！");
		}
		checkColor(color);
		checkPosition(x, y);
		if(pieces[x][y] != 0){
			throw new RuntimeException("此位置已经有棋子，不能再下!");
		}
		pieces[x][y] = color;
		isOver = isGameOver(x, y, color);
		if(isOver){
			return color;
		} else {
			next();
			return 0;
		}
	}

	public int getCurrentColor() {
		return currentColor;
	}

	public void setCurrentColor(int currentColor) {
		this.currentColor = currentColor;
	}
	
	public void drawChessboard(Graphics g){
		drawChessboardLine(g);
		drawPieces(g);
	}
	
	private void drawChessboardLine(Graphics g){
		ImageIcon backImg = new ImageIcon(getClass().getResource("/resource/bg.png"));
		g.drawImage(backImg.getImage(), 0, 0, getChessboardWidth(), getChessboardHeight(), null);
		g.setColor(Color.GRAY);
		for(int i = 0; i < GRID_NUM; i++){
			for(int j=0; j < GRID_NUM; j++){
				g.drawRect(i*GRID_SIZE+BOARD_PADDING, j*GRID_SIZE+BOARD_PADDING, GRID_SIZE, GRID_SIZE);
			}
		}
		g.setColor(Color.DARK_GRAY);
		for(int i = 0; i < GRID_NUM; i++){
			for(int j=0; j < GRID_NUM; j++){
				if(i == 3 && j==3 || 
						i==11 && j == 11 || 
						i== 3 && j==11 || 
						i == 11 && j==3 ||
						i == 7 && j == 7){
					g.fillRect(i*GRID_SIZE+BOARD_PADDING-2, j*GRID_SIZE+BOARD_PADDING-2, 5, 5);
				}
			}
		}
	}
	
	private void drawPieces(Graphics g){
		ImageIcon blackImg = new ImageIcon(getClass().getResource("/resource/black.png"));
		ImageIcon whiteImg = new ImageIcon(getClass().getResource("/resource/white.png"));
		
		for(int i = 0; i <= GRID_NUM; i++){
			for(int j=0; j <= GRID_NUM; j++){
				if(pieces[i][j] != 0){
					int x = i * GRID_SIZE+BOARD_PADDING - PIECE_SIZE/2;
					int y = j * GRID_SIZE+BOARD_PADDING - PIECE_SIZE/2;
					if(pieces[i][j] == PIECE_BLACK){
						g.drawImage(blackImg.getImage(), x, y, null);
					} else {
						g.drawImage(whiteImg.getImage(), x, y, null);
					}
					
				}
			}
		}
	}
	
	
	private boolean isGameOver(int x, int y, int color) {
		//向左、向右、向上、向下、左上、右上、右下、左下
		int[][] moves = new int[][]{{-1, 0},{1, 0},{0,-1},{0, 1},
									{-1,-1},{1, 1},{1,-1},{-1,1}};
		
		int num = 1;
		for (int i = 0; i < moves.length; i = i + 2) {
			num = 1;
			
			int nx = x + moves[i][0];
			int ny = y + moves[i][1];
			while (nx >= 0 && nx <= GRID_NUM && ny >= 0 && ny <= GRID_NUM + 1) {
				if (pieces[nx][ny] == color) {
					num++;
				} else {
					break;
				}
				nx += moves[i][0];
				ny += moves[i][1];
			}

			nx = x + moves[i + 1][0];
			ny = y + moves[i + 1][1];
			while (nx >= 0 && nx <= GRID_NUM && ny >= 0 && ny <= GRID_NUM) {
				if (pieces[nx][ny] == color) {
					num++;
				} else {
					break;
				}
				nx += moves[i + 1][0];
				ny += moves[i + 1][1];
			}
			if (num >= 5) {
				return true;
			}
		}
		return false;
	}
	
	
	public int getChessboardWidth(){
		return GRID_NUM*GRID_SIZE + 2*BOARD_PADDING;
	}
	
	public int getChessboardHeight(){
		return GRID_NUM*GRID_SIZE + 2*BOARD_PADDING;
	}

	public int[][] getPieces() {
		return pieces;
	}
	
	public void next(){
		if(currentColor == PIECE_BLACK){
			currentColor = PIECE_WHITE;
		} else {
			currentColor = PIECE_BLACK;
		}
	}
	
	public boolean isOver(){
		return isOver;
	}
	
}
